home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / games / monolife.arc / MONOLIFE.S < prev    next >
Text File  |  1985-11-20  |  9KB  |  281 lines

  1. ; Play Conway's Game of Life on a monochrome ST.  This program was
  2. ; developed with the AssemPro assembler from Abacus Software.
  3. ;
  4. ; Designed and programmed by Eric Bergman-Terrell, 1987
  5. ;
  6. ; Press left mouse button to quit the program.
  7. ; Press right mouse button to get a new cell generation.
  8.  
  9.      text
  10.  
  11.      ilabel     c:\assemble\tos\tos.l
  12.  
  13. ; Pixels in x-dimension
  14. y_pixels  = 400
  15.  
  16. ; Pixels in y-dimension
  17. x_pixels  = 640
  18.  
  19. ; Width of rectangle
  20. pix_x_len =   4
  21.  
  22. ; Height of rectangle
  23. pix_y_len =   4
  24.  
  25. ; Cells in x-dimension
  26. x_cells   = x_pixels / pix_x_len
  27.  
  28. ; Cells in y-dimension
  29. y_cells   = y_pixels / pix_y_len
  30.  
  31. start:       gem_init
  32.              ; Get a local stack for use by this program.
  33.              lea       stack_top, sp
  34.              bsr       init_gr
  35.              ; Make the first generation of cells.
  36. restart:     bsr       randomize
  37.              bsr       init_old
  38.              ; Plot the current generation to the screen.
  39. loop_2:      bsr       plot
  40.              bsr       new_to_old
  41.              ; Generate the next generation.
  42.              bsr       update
  43.              ; If right mouse button is pressed, quit.
  44.              ; If left mouse button is pressed, create a new
  45.              ; random generation.
  46.              vq_mouse  gr_handle, d0, d1, d2
  47.              and.w     #3,        d0
  48.              beq.s     loop_2
  49.              and.w     #1,        d0
  50.              beq.s     restart
  51. quit:        gem_exit
  52.              rts
  53.  
  54.  
  55. ; Copy new generation into old generation
  56. new_to_old:  lea    oldgen, a0
  57.              lea    newgen, a1
  58.              lea    oldend, a2
  59. assign_lp:   move.w (a1)+,  (a0)+
  60.              cmp.l  a2,     a0
  61.              ble.s  assign_lp
  62.              rts
  63.  
  64. ; Give the old generation an initial value totally different than
  65. ; the initial value of the new generation.
  66. init_old:    lea     oldgen, a0
  67.              lea     oldend, a1
  68. init_lp:     move.b  #2,     (a0)+
  69.              cmp.l   a1,     a0
  70.              ble.s   init_lp
  71.              rts
  72.  
  73.  
  74. ; Generate a new generation of cells.  For each nonempty cell, if it
  75. ; has two or three neighbors, it survives, otherwise it dies.  If an
  76. ; empty cell has three neighbors, it becomes nonempty.  A cell can
  77. ; have up to eight neighbors:
  78. ;
  79. ; -------
  80. ; |N|N|N|
  81. ; -------
  82. ; |N|*|N|   * denotes a cell
  83. ; -------   N denotes a cell's neighbors
  84. ; |N|N|N|
  85. ; -------
  86. ;
  87.  
  88. update:      lea    oldgen - 1, a0
  89.              lea    newgen - 1, a1
  90.  
  91.              clr.w  d0 ; x-coordinate
  92.              clr.w  d1 ; y-coordinate
  93.  
  94. loop_5:      addq.l #1,         a0
  95.              addq.l #1,         a1
  96.  
  97.              clr.b  d3 ; Compute number of oldgen[x, y]'s
  98.                        ; neighbors.
  99.  
  100.              ; Don't compute neighbors of a cell on a border.
  101.              cmp.w  #0,         d0
  102.              beq                update_cell
  103.  
  104.              cmp.w  #0,         d1
  105.              beq                update_cell
  106.  
  107.              cmp.w  #(x_cells - 1), d0
  108.              beq                update_cell
  109.  
  110.              cmp.w  #(y_cells - 1), d1
  111.              beq                update_cell
  112.  
  113.              ; Count the neighbors of the current cell.
  114.              move.l a0,         a4
  115.              subq.l #1,         a4
  116.              add.b  (a4),       d3
  117.              move.l a0,         a4
  118.              addq.l #1,         a4
  119.              add.b  (a4),       d3
  120.  
  121.              move.l a0,             a4
  122.              sub.l  #(x_cells + 1), a4
  123.  
  124.              add.b  (a4)+,          d3
  125.              add.b  (a4)+,          d3
  126.              add.b  (a4),           d3
  127.  
  128.              move.l a0,             a4
  129.              add.l  #(x_cells - 1), a4
  130.  
  131.              add.b  (a4)+,          d3
  132.              add.b  (a4)+,          d3
  133.              add.b  (a4),           d3
  134.  
  135. update_cell: tst.b    (a0)
  136.              beq.s    empty
  137.              cmp.b    #2,       d3
  138.              beq.s    do_set
  139.              cmp.b    #3,       d3
  140.              beq.s    do_set
  141.              bra.s    do_clear
  142. do_set:      move.b   #1,       (a1)
  143.              bra.s    next_x2
  144. do_clear:    clr.b    (a1)
  145.              bra.s    next_x2
  146. empty:       cmp.b    #3,       d3
  147.              beq.s    do_set
  148.              bra.s    do_clear
  149. next_x2:     addq.w   #1,             d0
  150.              cmp.w    #(x_cells - 1), d0
  151.              bgt.s    next_y2
  152.              bra.s    loop_5
  153. next_y2:     clr.w    d0
  154.              addq.w   #1,             d1
  155.              cmp.w    #(y_cells - 1), d1
  156.              bgt.s    quit2
  157.              bra      loop_5
  158. quit2:       rts
  159.  
  160.  
  161. ; Prepare to plot to screen.
  162. init_gr:     vs_clip       gr_handle, #1, px
  163.              vswr_mode     gr_handle, #1, d0
  164.              vsf_color     gr_handle, #1, d0
  165.              vsl_color     gr_handle, #1, d0
  166.              v_hide_c      gr_handle
  167.              ; Make sure that rectangle perimeters are not drawn.
  168.              vsf_perimeter gr_handle, #0, d0
  169.              bsr           clear
  170.              rts
  171.  
  172. ; Clear the screen.
  173. clear:       vsf_interior gr_handle,       #8,         d1
  174.              lea          pxy_array,       a3
  175.              clr.w        (a3)+
  176.              clr.w        (a3)+
  177.              move.w       #(x_pixels - 1), (a3)+
  178.              move.w       #(y_pixels - 1), (a3)
  179.              v_bar        gr_handle,       pxy_array
  180.              rts
  181.  
  182. ; Generate a random cell pattern.
  183. randomize:   lea     newgen,         a3
  184.              lea     newend,         a4
  185. loop:        random
  186.              move.w  d0,             d3
  187.              and.w   #7,             d3
  188.              asr.b   d3,             d0
  189.              and.l   #1,             d0
  190.              move.b  d0,             (a3)+
  191.              cmp.l   a4,             a3
  192.              bgt.s   trim
  193.              bra.s   loop
  194.              ; Remove cells from the border of the rectangle.
  195. trim:        lea     newgen,         a3
  196.              subq.l  #1,             a3
  197.              clr.w   d0                  ; x-coordinate
  198.              clr.w   d1                  ; y-coordinate
  199.              ; Clear all cells on borders.
  200. trim_loop:   addq.l  #1,             a3
  201.              tst.w   d0
  202.              beq     clear_cell
  203.              cmp.w   #(x_cells - 1), d0
  204.              beq     clear_cell
  205.              cmp.w   #0,             d1
  206.              beq     clear_cell
  207.              cmp.w   #(y_cells - 1), d1
  208.              beq     clear_cell
  209. next_x_2:    addq.w  #1,             d0
  210.              cmp.w   #(x_cells - 1), d0
  211.              bgt.s   next_y_2
  212.              bra.s   trim_loop
  213. next_y_2:    clr.w   d0
  214.              addq.w  #1,             d1
  215.              cmp.w   #(y_cells - 1), d1
  216.              bgt.s   return_3
  217.              bra     trim_loop
  218. return_3:    rts
  219.              ; Remove one cell from a border of the rectangle.
  220. clear_cell:  clr.b   (a3)
  221.              bra.s   next_x_2
  222.  
  223.  
  224. ; Plot a cell pattern to the screen.
  225. plot:        lea          newgen,           a0
  226.              lea          oldgen,           a2
  227.              clr.w        d0       ; x-coordinate
  228.              clr.w        d1       ; y-coordinate
  229. draw_loop:   clr.w        d3
  230.              move.b       (a0)+,            d3
  231.              move.b       (a2)+,            d4
  232.              cmp.b        d3,               d4
  233.              beq          next_x
  234.  
  235.              ; Draw the rectangle.
  236.              lea          pxy_array,        a1
  237.              move.w       d0,               (a1)+
  238.              move.w       d1,               (a1)+
  239.              move.w       d0,               d5
  240.              move.w       d1,               d6
  241.              addq.w       #(pix_x_len - 1), d5
  242.              addq.w       #(pix_y_len - 1), d6
  243.              move.w       d5,               (a1)+
  244.              move.w       d6,               (a1)
  245.  
  246.              ; Save registers.
  247.              movem.l      d0-d3/a0-a2,      -(sp)
  248.  
  249.              vsf_interior gr_handle,        d3,        d2
  250.              v_bar        gr_handle,        pxy_array
  251.  
  252.              ; Restore registers.
  253.              movem.l      (sp)+,            d0-d3/a0-a2
  254.  
  255. next_x:      addq.w       #pix_x_len